/**
 * @copyright (C) COPYRIGHT 2022 Fortiortech Shenzhen
 * @file      Interrupt.c
 * @author    Fortiortech  Appliction Team
 * @date      2022-07-13
 * @brief     This file contains interrupt function used for Motor Control.
 */



#include <MyProject.h>

extern uint8 data g_1mTick;                   ///< 1ms滴答信号，每隔1ms在SYSTICK定时器被置1，需在大循环使用处清零
extern void HardwareInit(void);
extern void SoftwareInit(void);
uint16 xdata spidebug[4] = { 0 };             ///< SPI debug 输出通道缓存，SPI调试器会将该变量值进行输出


/**
 * @brief        低于预警中断与过温中断
 * @brief        开启低压检测中断后,MCU会对输入电压进行监测,当输入电压低于设定值，则会触发中断
 * @brief       
 * @date         2022-12-29
 */
void LVW_TSD_INT(void) interrupt 0  //LVW & TSD interrupt
{
    if (ReadBit(LVSR, LVWIF))
    {
        if (ReadBit(LVSR, LVWF))
        {
            mcFaultSource = FaultUnderVoltageDC;
            ClrBit(LVSR, LVWF);
        }
        
        ClrBit(LVSR, LVWIF);
    }
}

/**
 * @brief        外部中断0
 * @brief        一般用于响应IPM的FO过流信号
 * @date         2022-07-14
 */
void EXTERN0_INT(void) interrupt 1                  //  外部中断0
{
    if (IF0)
    {
        IF0 = 0;                                // clear P00 interrupt flag
    }
}


/** 
 * @brief        外部中断1，用于PWM信号唤醒
 * @date         2023-07-26
 */
void EXTERN1_INT(void) interrupt 2              //  外部中断1
{
    if (P1_IF)
    {
       if (SleepSet.SleepFlag == 1)
        {
            SleepSet.SleepFlag = 0;
            /*系统软件复位*/
            SetBit(RST_SR, SOFTR);
        }
        P1_IF = 0;                           
    }
}

/**
 * @brief        FOC中断(Drv中断),每个载波周期执行一次，用于处理响应较高的程序，中断优先级第二
 * @date         2022-07-14
 */
void DRV_ISR(void) interrupt 3
{
    if (ReadBit(DRV_SR, FGIF))
    {
        DRV_SR = (SYSTIE | FGIF | DCIM1 | SYSTIF) & (~FGIF);
    }
    
    if (ReadBit(DRV_SR, DCIF))    // 比较中断
    {
        #if (DBG_MODE ==  DBG_SPI_SW)            //软件调试模式
        spidebug[0] = FOC__THETA;
        spidebug[1] = mcFocCtrl.AlignAngle;
        spidebug[2] = mcFocCtrl.AlignAngle_Temp;
        #endif

        DRV_SR = (DRV_SR | SYSTIF) & (~DCIF);
    }
}



/**
 * @brief        Timer2中断服务函数
 * @note         本例程中用于RSD顺逆风检测
 * @date         2022-07-14
 */
void TIM2_INT(void) interrupt 4
{
     static uint8 Toutcnt = 0,PWMcnt=0,PWMall=0;
    if (ReadBit(TIM2_CR1, T2IR))
    {
        ClrBit(TIM2_CR1, T2IR);
    }

    if (ReadBit(TIM2_CR1, T2IP)) // 周期中断
    {
        mcPwmInput.TimerDR = TIM2__DR;
        mcPwmInput.TimerARR = TIM2__ARR;
        if ((mcPwmInput.TimerARR > 375) && (mcPwmInput.TimerARR < 7500))//最小6hz
        { 
					if(PWMcnt<10)
					  PWMcnt++;
            if ((mcPwmInput.isUpdate == 0)&&(PWMcnt>2)) // 空闲状态下  允许更新DR与ARR
            {
                mcPwmInput.TimerDR = TIM2__DR;
                mcPwmInput.TimerARR = TIM2__ARR;
                mcPwmInput.isUpdate = 1;
                Toutcnt = 0;
            }
        }

				PWMall=0;
        ClrBit(TIM2_CR1, T2IP);
    }

    if (ReadBit(TIM2_CR1, T2IF))
    {
				PWMcnt=0;
				if(PWMall<10)
					PWMall++;
        if ((mcPwmInput.isUpdate == 0)&&(PWMall>2)) // 空闲状态下  允许更新DR与ARR
        {
            if (ReadBit(P1, PIN0)) // PWM 0%  持续2s关闭输出
            {
                  if (Toutcnt < 10)
                {
                     Toutcnt++;
                }
								else
								{
                    mcPwmInput.isUpdate = 1;
                }
                mcPwmInput.TimerDR = 4000;
                mcPwmInput.TimerARR = 4000;
            }
            else // PWM 为1000%
            {

                mcPwmInput.TimerDR = 0;
                mcPwmInput.TimerARR = 4000;
            }
						mcPwmInput.isUpdate = 1;
        }
        ClrBit(TIM2_CR1, T2IF);
    }
}



/** 
 * @brief        定时器3中断服务函数
 * @note         本例程中用于PWM调速信号捕获
 * @date         2022-07-14
 */
void TIM3_INT(void) interrupt 9
{
    if (ReadBit(TIM3_CR1, T3IR))
    {
        ClrBit(TIM3_CR1, T3IR);
    }
    
    if (ReadBit(TIM3_CR1, T3IP))//周期中断
    {
        ClrBit(TIM3_CR1, T3IP);
    }
    
    if (ReadBit(TIM3_CR1, T3IF))
    {
        ClrBit(TIM3_CR1, T3IF);
    }
}



/**
 * @brief        滴答定时器，默认用于产生1ms定时间隔
 * @date         2022-07-14
 */
void SYStick_INT(void) interrupt 10
{
    if (ReadBit(DRV_SR, SYSTIF))          // SYS TICK中断
    {
        g_1mTick = 1;
        DRV_SR = (DRV_SR | DCIF) & (~SYSTIF);
    }
}



/**
 * @brief        比较器硬件过流保护，该中断仅提供 故障码 赋值,用于状态机的切换。
 *               需要开启比较器CMP3  发生过流 自动清除MOE功能
 * @date         2022-07-14
 */

void CMP3_INT(void)  interrupt 12
{
    if (ReadBit(CMP_SR, CMP3IF))
    {
        if (mcState != mcPosiCheck)
        {
            mcFaultSource = FaultHardOVCurrent;     // 硬件过流保护
        }
        
        ClrBit(CMP_SR, CMP3IF);
    }
}
#if (SPEED_MODE == LINMODE)
void int14(void) interrupt 14
{
	if (ReadBit(LIN_CR, LINIE))
	{
		if (ReadBit(LIN_SR, LINREQ))
		{
			LIN_list(); //读取ID号并处理信号
            SleepSet.SleepDelayCout = 0;    //有LIN信号清零
			SetReg(LIN_SR, LINDONE | LINIDLE | LINREQ, LINIDLE | LINDONE);
		}

		if (ReadBit(LIN_SR, LINDONE))
		{
			ReceiveSYS(LIN_ID);
			SetReg(LIN_SR, LINDONE | LINIDLE | LINREQ, LINIDLE | LINREQ); //数据收发完成
		}

		if (ReadBit(LIN_CSR, LINWAKEUP)) //唤醒信号
		{
			SetReg(LIN_CSR, LINWAKEUP | CLRERR, CLRERR);
		}

		if (ReadBit(LIN_SR, LINIDLE)) //总线空闲
		{
			SetReg(LIN_SR, LINDONE | LINIDLE | LINREQ, LINDONE | LINREQ);
		}

		if (ReadBit(LIN_SR, ERRSYNC | ERRPRTY | ERRCHK)) //错误中断
		{
			if(ReadBit(LIN_SR,ERRPRTY))//检测到ID错误复位LIN
			{
				LIN_CR=0;
				LIN_SR=0;
				LIN_CSR=0;
				LIN_BAUD=0;
				LIN_Init();
			}
			ClrBit(LIN_CSR, CLRERR);
		}
        if (ReadBit(LIN_CSR, CLRERR) //位错误中断
		{
            ClrBit(LIN_CSR, CLRERR);
        }
        
	}
}
#endif
